package fr.utbm.gi.in56.ads;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

import fr.utbm.gi.in56.database.ConnectionPool;
import fr.utbm.gi.in56.database.ConnectionServlet;
import fr.utbm.gi.in56.error.ErrorType;
import fr.utbm.gi.in56.notification.NotificationType;
import fr.utbm.gi.in56.user.UserBean;

/**
 * Servlet implementation class UploadImage
 * 
 * @author Adrien Hoffer & Tarik Belabbas
 */
@WebServlet("/PostSellAdServlet")
public class PostSellAdServlet extends AdServlet
{
	private static final long	serialVersionUID	= 1L;
	
	private final long maxUploadSize = 1048576L;
	
	private final String authorizedContentType = "image/jpeg"; //$NON-NLS-1$

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public PostSellAdServlet()
	{
		super();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doPost( HttpServletRequest request,
			HttpServletResponse response ) throws ServletException, IOException
	{
		request.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
		
		boolean isMultipart = ServletFileUpload.isMultipartContent( request );
		if ( !isMultipart )
		{
			System.out.println( "File Not Uploaded" ); //$NON-NLS-1$
		}
		else
		{
			FileItemFactory factory		= new DiskFileItemFactory();
			ServletFileUpload upload	= new ServletFileUpload( factory );
			List< FileItem > items = null;
			try
			{
				items = upload.parseRequest( request );
			}
			catch ( FileUploadException _exception )
			{
				_exception.printStackTrace();
				
				returnError( request, response, ErrorType.POST_UPLOAD_FAILED );
				return;
			}
			
			String title		= null;
			int idBrand			= 0;
			int idModel			= 0;
			int vehicleYear		= 0;
			int kmNb			= 0;
			int idEnergy		= 0;
			int automatic		= 0;
			int price			= 0;
			String description	= null;
			boolean hasImage	= false;
			FileItem imageItem	= null;
			
			Iterator< FileItem > it = items.iterator();
			while ( it.hasNext() )
			{
				FileItem fileItem = ( FileItem ) it.next();
				
				// If the item is a form field, read it
				if ( fileItem.isFormField() )
				{
					String fieldName = fileItem.getFieldName();
					String fieldValue = fileItem.getString("UTF-8").trim();
					
					if ( fieldName.compareTo( "title" ) == 0 ) //$NON-NLS-1$
					{
						title = fieldValue;
						
						if( title.isEmpty() )
						{
							returnError( request, response, ErrorType.EDIT_TITLE_EMPTY );
							return;
						}
					}
					else if ( fieldName.compareTo( "brand" ) == 0 ) //$NON-NLS-1$
					{
						idBrand = Integer.parseInt( fieldValue );
					}
					else if ( fieldName.compareTo( "model" ) == 0 ) //$NON-NLS-1$
					{
						idModel = Integer.parseInt( fieldValue );
					}
					else if ( fieldName.compareTo( "vehicle_date" ) == 0 ) //$NON-NLS-1$
					{
						vehicleYear = Integer.parseInt( fieldValue );
					}
					else if ( fieldName.compareTo( "km_nb" ) == 0 ) //$NON-NLS-1$
					{
						if( fieldValue.isEmpty())
						{
							kmNb = -1;
						}
						else
						{
							try
							{
								kmNb = Integer.parseInt( fieldValue );
							}
							catch (NumberFormatException e)
							{
								returnError( request, response, ErrorType.FIELD_NAN );
								return;
							}
						}
					}
					else if ( fieldName.compareTo( "energy" ) == 0 ) //$NON-NLS-1$
					{
						idEnergy = Integer.parseInt( fieldValue );
					}
					else if ( fieldName.compareTo( "is_automatic" ) == 0 ) //$NON-NLS-1$
					{
						automatic = Integer.parseInt( fieldValue );
					}
					else if ( fieldName.compareTo( "price" ) == 0 ) //$NON-NLS-1$
					{
						if( fieldValue.isEmpty())
						{
							price = -1;
						}
						else
						{
							try
							{
								price = Integer.parseInt( fieldValue );
							}
							catch (NumberFormatException e)
							{
								returnError( request, response, ErrorType.FIELD_NAN );
								return;
							}
						}
					}
					else if ( fieldName.compareTo( "description" ) == 0 ) //$NON-NLS-1$
					{
						description = fieldValue;
					}
				}
				else // The item is the file to upload
				{					
					if ( !fileItem.getName().isEmpty() )
					{
						if ( checkFileUpload( request, response, fileItem ) )
						{
							hasImage = true;
							imageItem = fileItem;
						}
						else
						{
							return;
						}
					}
				}
			}// end while loop on iterator
			
			AdsManager adsBuyMg = new AdsManager( getConnection() );
			
			// Get the current user
			HttpSession session = request.getSession( true );
			UserBean user = (UserBean)session.getAttribute( "currentSessionUser" ); //$NON-NLS-1$
			
			int createdAdId = adsBuyMg.postSellAd( title, user.getLogin(),
					description,idBrand, idModel, automatic, price, vehicleYear,
					kmNb, idEnergy, hasImage );
			
			if(  createdAdId == -1 )
			{
				returnError( request, response, ErrorType.DB_ERROR );
				return;
			}
			
			if ( hasImage )
			{
				// Write file
				String filename = new String( createdAdId + ".jpg" );
				File savedFile1 = new File(System.getProperty("catalina.base"), "wtpwebapps/IN56_lentrepot/ressources/images/" + filename );
				File savedFile2 = new File(System.getProperty("catalina.home"), "/webapps/IN56_lentrepot/ressources/images/" + filename );
				try
				{
					imageItem.write( savedFile1 );
					imageItem.write( savedFile2 );
				}
				catch ( Exception _exception )
				{
					_exception.printStackTrace();
				}
			}
			
			ServletContext context	= getServletContext();
			String key				= ConnectionServlet.getPoolKey();
			Object object			= context.getAttribute( key );
						
			AdSell adsell = adsBuyMg.getAdSell( createdAdId );
			SellAdMatcher bsm = new SellAdMatcher( adsell, (ConnectionPool)object, user.getLogin() );
			bsm.run();
			
			request.setAttribute( "notification", NotificationType.AD_SUBMITTED ); //$NON-NLS-1$
			RequestDispatcher rd = request.getRequestDispatcher("notification.jsp"); //$NON-NLS-1$
			rd.forward( request, response );
			
			return;
		}
	}
	
	/**
	 * Sets the error as request attribute and forward to previous page.
	 * 
	 * @param _error the error
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void returnError( HttpServletRequest request,
			HttpServletResponse response, ErrorType _error ) throws ServletException, IOException
	{
		ErrorType result = forwardEnergyAndCarLists( request, response );
		if ( result != ErrorType.NONE )
		{
			request.setAttribute( "error", result ); //$NON-NLS-1$
			RequestDispatcher rd = request.getRequestDispatcher("error.jsp"); //$NON-NLS-1$
			rd.forward( request, response );
		}
		else
		{
			request.setAttribute( "postAdError", _error ); //$NON-NLS-1$
			RequestDispatcher rd = request.getRequestDispatcher("postSellAd.jsp"); //$NON-NLS-1$
			rd.forward( request, response );
		}
	}
	
	/**
	 * Check the file to upload and returns <tt>true</tt> if there is no error.
	 * 
	 * @param request the servlet request
	 * @param response the servlet response
	 * @param fileItem the file item to upload
	 * @return <tt>true</tt> if there is no error
	 */
	private boolean checkFileUpload( HttpServletRequest request,
			HttpServletResponse response, FileItem fileItem )
	{
		try
		{	
			String imgDirectoy = "tomcat_images"; //$NON-NLS-1$
			if ( !( new File( imgDirectoy ) ).exists() )
			{
				boolean dirCreation = false;
				try
				{
					dirCreation = ( new File( imgDirectoy ) ).mkdir();
				}
				catch ( Exception e )
				{
					System.err.println( "Error: " + e.getMessage() ); //$NON-NLS-1$
					
					returnError( request, response, ErrorType.POST_UPLOAD_FAILED );
					return false;
				}
				
				if ( !dirCreation )
				{
					returnError( request, response, ErrorType.POST_UPLOAD_FAILED );
					return false;
				}
			}
			
			// Get the name attribute value of the <input type="file"> element
			//String fieldName = fileItem.getFieldName();

			// Get the size of the uploaded file in bytes
			long fileSize = fileItem.getSize();
			if ( fileSize > maxUploadSize )
			{
				returnError( request, response, ErrorType.POST_UPLOAD_MAX_SIZE );
				return false;
			}
			
			// Get the content type (MIME type) of the uploaded file
			String contentType = fileItem.getContentType();
			if ( contentType.compareTo( authorizedContentType ) != 0 )
			{
				returnError( request, response, ErrorType.POST_UPLOAD_INVALID_TYPE );
				return false;
			}
		}
		catch ( Exception _exception )
		{
			_exception.printStackTrace();
			return false;
		}
		
		return true;
	}
}
